using System;
using System.Collections.Generic;
using System.IO;
using System.ComponentModel;

namespace PSSymbolStore
{
    internal class PreParseEventArgs : CancelEventArgs
    {
        public string Line { get; set; }
        public bool ShouldParse { get; set; }

        public PreParseEventArgs()
        { }

        public PreParseEventArgs(bool cancel)
            : base(cancel)
        {
        }
    }

    internal delegate void PreParse(PreParseEventArgs e);
    
    internal class TransactionFileParser
    {
        internal static int TRANSACTION_ID_FIELD = 0;
        internal static int TRANSACTION_TYPE_FIELD = 1;
        internal static int FILE_OR_POINTER_FIELD = 2;
        internal static int TRANSACTION_DATE_FIELD = 3;
        internal static int TRANSACTION_TIME_FIELD = 4;
        internal static int PRODUCT_FIELD = 5;
        internal static int VERSION_FIELD = 6;
        internal static int COMMENT_FIELD = 7;
        internal static int DELETED_TRANSACTION_ID_FIELD = 2;

        private readonly string _serverFile;
        private string[] _serverFileContents;
        private readonly Dictionary<string, TransactionFileEntry> _entryMap = new Dictionary<string, TransactionFileEntry>();

        public TransactionFileParser(string serverFile, bool preLoad)
        {
            _serverFile = serverFile;
            if (preLoad)
            {
                ReadFile();
            }
        }

        private void ReadFile()
        {
            if (_serverFileContents == null)
            {
                _serverFileContents = File.ReadAllLines(_serverFile);
            }
        }

        public List<TransactionFileEntry> Parse()
        {
            return Parse(null);
        }

        public List<TransactionFileEntry> Parse(PreParse onPreParse)
        {
            var entries = new List<TransactionFileEntry>();

            // Read the file
            ReadFile();

            if ((_serverFileContents != null) && (_serverFileContents.Length > 0))
            {
                var args = new PreParseEventArgs();

                foreach (string line in _serverFileContents)
                {
                    args.Line = line;
                    args.ShouldParse = true;
                    args.Cancel = false;

                    try
                    {
                        if (onPreParse != null)
                        {
                            onPreParse(args);
                        }
                    }
                    catch { }

                    if (args.ShouldParse)
                    {
                        // Parse the line
                        TransactionFileEntry entry;
                        if (!_entryMap.TryGetValue(line, out entry))
                        {
                            entry = ParseLine(line);
                            if (entry != null)
                            {
                                _entryMap.Add(line, entry);
                            }
                        }

                        if (entry != null)
                        {
                            entries.Add(entry);
                        }
                    }

                    if (args.Cancel)
                    {
                        break;
                    }

                    //line = reader.ReadLine();
                }
            }

            return entries;
        }

        private static TransactionFileEntry ParseLine(string line)
        {
            string s = line.Trim();

            if (String.IsNullOrEmpty(s))
            {
                return null;
            }

            // Try to parse the CSV input
            List<string> fields = Helpers.ParseCSVLine(s);

            if (fields.Count == 0)
            {
                return null;
            }

            return new TransactionFileEntry(fields);
        }
    }
}
